package org.zsk.fastdev.redisson;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * redisson工具类
 * </p>
 *
 * @author zsk
 * @date 2020/11/26 下午4:48
 */
@Component("redissonUtil")
@Slf4j
public class RedissonUtil {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 阻塞锁
     *
     * @param redLockKey key值
     * @param leaseTime  失效时间
     * @param timeUnit   失效时间单位
     * @param commander  执行命令
     */
    public void lock(String redLockKey, long leaseTime, TimeUnit timeUnit, Commander commander) {
        RLock redLock = redissonClient.getLock(redLockKey);
        try {
            //阻塞锁
            log.debug("等待key为{}锁", redLockKey);
            redLock.lock(leaseTime, timeUnit);
            log.debug("成功获取key为：{}的锁，开始执行cmd", redLockKey);
            commander.execute();
            log.debug("key为：{}的锁，执行cmd结束", redLockKey);
        } catch (Exception e) {
            e.printStackTrace();
            log.debug("获取redis锁异常", e);
        } finally {
            //解锁
            redLock.unlock();
            log.debug("释放key为：{}的锁", redLock);
        }
    }

    /**
     * 阻塞锁
     *
     * @param redLockKey key值
     * @param commander  执行命令
     */
    public void lock(String redLockKey, Commander commander) {
        RLock redLock = redissonClient.getLock(redLockKey);
        try {
            //阻塞锁
            log.debug("等待key为{}锁", redLockKey);
            redLock.lock();
            log.debug("成功获取key为：{}的锁，开始执行cmd", redLockKey);
            commander.execute();
            log.debug("key为：{}的锁，执行cmd结束", redLockKey);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取redis锁异常", e);
        } finally {
            //解锁
            redLock.unlock();
            log.debug("释放key为：{}的锁", redLock);
        }
    }

    /**
     * 乐观锁
     *
     * @param redLockKey key值
     * @param waitTime   等待时间
     * @param leaseTime  失效时间
     * @param timeUnit   失效时间单位
     * @param commander  执行命令
     */
    public void tryLock(String redLockKey, long waitTime, long leaseTime, TimeUnit timeUnit, Commander commander) {
        RLock redLock = redissonClient.getLock(redLockKey);
        boolean isLock;
        try {
            log.debug("等待key为{}锁", redLockKey);
            isLock = redLock.tryLock(waitTime, leaseTime, timeUnit);
            if (isLock) {
                log.debug("成功获取key为：{}的锁，开始执行cmd", redLockKey);
                commander.execute();
                log.debug("key为：{}的锁，执行cmd结束", redLockKey);
            } else {
                log.debug("获取key为：{}的锁失败", redLockKey);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.debug("获取redis锁异常", e);
        } finally {
            //解锁
            redLock.unlock();
            log.debug("释放key为：{}的锁", redLock);
        }
    }
}
